#include <allegro.h>
#include <stdio.h>
#include <apeg.h>

#define GFX_W 1280
#define GFX_H 720
#define NB_IMAGES 4

struct Perso {
	BITMAP * img_right[NB_IMAGES];/*!< Tablaau des animation a droite*/
	BITMAP * img_left[NB_IMAGES];/*!< Tableau des animations a gauche */
	int x, y; /*!< position personnage*/
	int direction; /*!direction personnage haut , dte, gauche .. */
};
typedef struct Perso Perso;

int X,Y;
BITMAP *Buffer;
int last_direction;
/*int cx,cy;
 cx= 1280/2;
 cy=720/2;*/

int get_pixel(BITMAP* Buffer,int x,int y);



BITMAP* load_background_bmp(char chemin_background[]);
BITMAP* load_background1_bmp(char chemin_background_col[]);
void draw_background(BITMAP *Background,BITMAP*Buffer);
void destroy_background(BITMAP * Background);


void load_perso(Perso *perso);
void destroy_perso(Perso *perso);
void init_perso(Perso *perso);

void move_perso_right(Perso *perso,int *compteur,BITMAP * Background,int pix1);
void move_perso_left(Perso *perso,int *compteur,BITMAP * Background,int pix2);
void gravity_perso(Perso *perso,BITMAP * Background,int pix3);
void jump_perso(Perso *perso,BITMAP * Background,int pix4); 

void move_perso(Perso *perso,int *compteur,BITMAP * Background,int pix1,int pix2,int pix3,int pix4);
void draw_perso(Perso perso,BITMAP *Buffer, int compteur);



//INSTALL SOUND


	

int main()
{


BITMAP *Buffer;
BITMAP *img[3];
SAMPLE *music;
int son_music ;
	char chemin_background[]="./map_elfe.bmp";
        char chemin_background_col[]="./backgroundC.bmp";

	BITMAP *Background=NULL;
	BITMAP *BackgroundCol=NULL;
	Perso perso;

	int compteur;
 int pix1,pix2,pix3,pix4;

int i=0;


int menu=0;
int continuer=1 ;	
X=0;
Y=0;
BITMAP *img0;
BITMAP *img1;
BITMAP *img2;
BITMAP *img3;
BITMAP *img4;
BITMAP *img5;
BITMAP *img6;
int pause=(-1);
int inmenu=1;
int a=0;

/** @brief General initialization function */
allegro_init();

if(install_sound(DIGI_AUTODETECT, MIDI_AUTODETECT, NULL)) {
allegro_message("Sound Error: %s", allegro_error);
return 1;
}

if (install_keyboard() == -1) {
allegro_message("Error! %s", allegro_error);
return -1;
}
set_color_depth(32);
if (set_gfx_mode(GFX_AUTODETECT_FULLSCREEN, 1280, 720, 0, 0) != 0) {
set_gfx_mode(GFX_TEXT, 0, 0, 0, 0); /* here’s the command for text mode */
allegro_message("Unable to initialize video mode!\n%s\n", allegro_error);
return 1;
}

/** *@brief play sound*/
music=load_wav("./son.wav");
if (!music) {
textprintf(screen,font,0,0,makecol(255,255,255),"error music ");
readkey();
return 0;
}
//Voulume SOUND
set_volume(255, 255);

//Play music
son_music=play_sample(music,128,128,1000,0) ;
Buffer = create_bitmap(1280, 720);
img[0]= load_bitmap("./nouveau.bmp", NULL);
img[1]= load_bitmap("./continuer.bmp", NULL);
img[2]= load_bitmap("./quitter.bmp", NULL);

Buffer = create_bitmap(1280, 720);
apeg_play_mpg("Cinematique_intro.ogv", screen, FALSE, NULL); //this is the one that plays the video
while(continuer!=0)
{

	clear_bitmap(Buffer);

	if (key[KEY_ENTER])
	{
		continuer=0;
	}
	
	
	if(  key[KEY_DOWN]  )
		i++;

	
	if(  key[KEY_UP]  )
		i--;
	
	menu=(i)%3;


	blit(img[menu], Buffer, 0, 0, 0, 0, img[menu]->w, img[menu]->h);	
	blit(Buffer, screen, 0, 0, 0, 0, SCREEN_W, SCREEN_H); 
	
}



	 

if (menu==0)
{


	Buffer = create_bitmap(SCREEN_W, SCREEN_H);
	//loading images
	//loading mario
	load_perso(&perso);
	//loading background + background collision
	Background=load_background_bmp(chemin_background);
	//loading background collision Map
 	BackgroundCol=load_background1_bmp(chemin_background_col);
        
	//init position & direction
	compteur = 0;
	init_perso(&perso);

	while (!key[KEY_ESC]) {
		//vider le buffer
		clear_bitmap(Buffer);
		//moving mario
		move_perso(&perso,&compteur,BackgroundCol,pix1,pix2,pix3,pix4);
		//drawing background
		
              // draw_background(BackgroundCol,Buffer);
               draw_background(Background,Buffer);
		//drawing mario
           pix1=get_pixel(BackgroundCol,perso.x+ perso.img_right[0]->w+X,perso.y + perso.img_right[0]->h /2+Y);
           pix2=get_pixel(BackgroundCol,perso.x+X,perso.y + perso.img_left[0]->h /2+Y);
	   pix3=get_pixel(BackgroundCol,perso.x+ perso.img_right[3]->w /2+X,perso.y+Y);
	   pix4=get_pixel(BackgroundCol,perso.x+ perso.img_right[0]->w /2+X,perso.y + perso.img_right[0]->h+Y);





		draw_perso(perso,Buffer,compteur);
		//blit Buffer to screen
		blit(Buffer, screen, X, Y, 0, 0, SCREEN_W, SCREEN_H);

		if (compteur == 10000)
			compteur = 0;

if(key[KEY_P])
{

clear_bitmap(Buffer);
Buffer = create_bitmap(1280, 720);
img0= load_bitmap("./menu_pause1.bmp", NULL);
img1= load_bitmap("./menu_pause2.bmp", NULL);
img2= load_bitmap("./menu_pause3.bmp", NULL);
img3= load_bitmap("./menu_pause4.bmp", NULL);
img4= load_bitmap("./menu_pause5.bmp", NULL);
img5= load_bitmap("./commande.bmp", NULL);
img6= load_bitmap("./nehl.bmp", NULL);

	blit(img0, Buffer, 0, 0, 0, 0, img0->w, img0->h);	
	blit(Buffer, screen, 0, 0, 0, 0, SCREEN_W, SCREEN_H);



	while (!key[KEY_ESC]) {

	clear_bitmap(Buffer);

	if(  key[KEY_DOWN] && (inmenu==1) )	
	{pause++;
	

		if (pause==0)
		{	
	
	blit(img0, Buffer, 0, 0, 0, 0, img0->w, img0->h);	
	blit(Buffer, screen, 0, 0, 0, 0, SCREEN_W, SCREEN_H);
a=1;
	}
	else if (pause==2)
	{

	blit(img2, Buffer, 0, 0, 0, 0, img2->w, img2->h);	
	blit(Buffer, screen, 0, 0, 0, 0, SCREEN_W, SCREEN_H);
a=2;
	}
	else if (pause==1)
	{	
	blit(img1, Buffer, 0, 0, 0, 0, img1->w, img1->h);	
	blit(Buffer, screen, 0, 0, 0, 0, SCREEN_W, SCREEN_H);	
a=3;
	}
if (pause==3)
	{	
	
	blit(img3, Buffer, 0, 0, 0, 0, img3->w, img3->h);	
	blit(Buffer, screen, 0, 0, 0, 0, SCREEN_W, SCREEN_H);
a=4;
	}
if (pause==4)
		{
pause=(-1);
	
	
	blit(img4, Buffer, 0, 0, 0, 0, img4->w, img4->h);	
	blit(Buffer, screen, 0, 0, 0, 0, SCREEN_W, SCREEN_H);
a=5;
	}
	


clear_keybuf();
readkey();
}

		if(  key[KEY_ENTER] && (a==2) )
{	


	blit(img5, Buffer, 0, 0, 0, 0, img5->w, img5->h);	
	blit(Buffer, screen, 0, 0, 0, 0, SCREEN_W, SCREEN_H);	

}
		if(  key[KEY_ENTER] && (a==3) )
{	


	blit(img6, Buffer, 0, 0, 0, 0, img6->w, img6->h);	
	blit(Buffer, screen, 0, 0, 0, 0, SCREEN_W, SCREEN_H);	

}

}
	destroy_bitmap(img0); //Release the bitmap data
	destroy_bitmap(img1); //Release the bitmap data
	destroy_bitmap(img2); //Release the bitmap data 
        destroy_bitmap(img3); //Release the bitmap data
        destroy_bitmap(img4); //Release the bitmap data
	destroy_bitmap(Buffer);
	}
}

	
	destroy_perso(&perso);
	destroy_background(Background);
      destroy_background(BackgroundCol);

	destroy_bitmap(Buffer);
}
	return (0);


 }	

/*
 * module background
 */
/**
* @fn BITMAP* load_background_bmp(char chemin_background[])
* @details Le champ chemin_background[] est un tableau qui a l'image de backgroun 
* @param
chemin_background ds le pc
* @return BITMAP */

BITMAP* load_background_bmp(char chemin_background[])
{
	BITMAP* Background;

	Background=load_bitmap(chemin_background, NULL);
	if(Background == NULL){
		set_gfx_mode(GFX_TEXT, 0, 0, 0, 0);
		allegro_message("Unable to load image !\n%s\n", allegro_error);
		return (NULL);
	}
	return (Background);

}

/**
* @fn BITMAP* load_background1_bmp(char chemin_background_col[])
* @details Le champ chemin_background_col[] est un tableau qui a l'image de background colision
* @param
chemin_background colision ds le pc
* @return BITMAP */

BITMAP* load_background1_bmp(char chemin_background_col[])
{
	BITMAP* BackgroundCol;

	BackgroundCol=load_bitmap(chemin_background_col, NULL);
	if(BackgroundCol == NULL){
		set_gfx_mode(GFX_TEXT, 0, 0, 0, 0);
		allegro_message("Unable to load image !\n%s\n", allegro_error);
		return (NULL);
	}
	return (BackgroundCol);

}

/**
* @fn void draw_background(BITMAP *Background,BITMAP*Buffer)
* @details Le champ Background dans le mémoire ( BITMAP) et le Buffer
* @param
 Drawing le Background
* @return void*/

void draw_background(BITMAP *Background,BITMAP*Buffer)
{
	blit(Background, Buffer, X, Y, 0, 0, SCREEN_W,SCREEN_H);
printf("%d            %d \n ",X,Y);
}

/**
* @fn void destroy_background(BITMAP * Background)
* @details Le champ Background dans le mémoire ( BITMAP) 
* @param
 Drawing le Background
* @return void*/
void destroy_background(BITMAP * Background)
{
	destroy_bitmap(Background);
}

/*
 * module mario
 */
/**
* @fn void load_perso(Perso *perso)
* @details Le champ perso est telecharger les images 
* @param
telecharger les image perso
* @return void*/
void load_perso(Perso *perso)
{
	int i;
	char buf[50];
	for (i = 0; i < NB_IMAGES; i++) {
		sprintf(buf, "./right%d.bmp", i);
		perso->img_right[i] = load_bitmap(buf, NULL);
		sprintf(buf, "./left%d.bmp", i);
		perso->img_left[i] = load_bitmap(buf, NULL);
	}
}

void destroy_perso(Perso *perso)
{
	int i;
	for (i = 0; i < NB_IMAGES; i++) {
		destroy_bitmap(perso->img_right[i]);
		destroy_bitmap(perso->img_left[i]);
	}

}
/**
* @fn void init_perso(Perso *perso)
* @details Le champ perso est metre les corrdooné du perso X et Y
* @param
X=SCRENN_W/2
Y=SCREEN_W/2
* @return void*/
void init_perso(Perso *perso)
{
	perso->direction = 0;
	perso->x = SCREEN_W/2;
	perso->y = SCREEN_H/2 ;
}
void move_perso_right(Perso *perso,int *compteur,BITMAP * Background ,int pix1)
{

 


	if (key[KEY_RIGHT] && (perso->x < SCREEN_W - perso->img_right[0]->w) && pix1 != 255) {
		*compteur+=1;

		//(perso->x)+=1;
		X++;
	//cx--;
		perso->direction = 0; //right

	}


}

void move_perso_left(Perso *perso,int *compteur,BITMAP * Background,int pix2)
{

	
if (key[KEY_LEFT] && (perso->x > 0 + perso->img_left[0]->w)&& pix2 != 255) {
		*compteur+=1;

		//(perso->x)-=1;
		X--;
	//cx++;

		perso->direction = 1; //left

	}
}

void jump_perso(Perso *perso,BITMAP * Background,int pix3)
{

	
if (key[KEY_UP]&& pix3 !=255 ) {
		//(perso->y)-=1;
	Y--;
//cy++;
		perso->direction = 2; //jump

	}

}

void gravity_perso(Perso *perso,BITMAP * Background,int pix4)
{

  
if (key[KEY_DOWN]&& pix4 != 255) {
	//(perso->y)+=1;
		Y++;
//cy--;
		perso->direction = 3; //jump

	}

}




void move_perso(Perso *perso,int *compteur,BITMAP * Background,int pix1,int pix2,int pix3,int pix4)
{
	move_perso_right(perso,compteur,Background,pix1);
	move_perso_left(perso,compteur,Background,pix2);
	jump_perso(perso,Background,pix3);
       gravity_perso(perso,Background,pix4);
	//add gravity
}
void draw_perso(Perso perso,BITMAP *Buffer, int compteur)
{
	//static int last_direction; 

     
	if (perso.direction == 0){ //moving right

		draw_sprite(Buffer, perso.img_right[compteur % (NB_IMAGES-1) ],perso.x, perso.y);
		last_direction=0;
	}

	if(perso.direction == 1){ //moving left

		draw_sprite(Buffer, perso.img_left[compteur % (NB_IMAGES-1) ],perso.x, perso.y);
		last_direction=1;
	}
	if (perso.direction == 2 && last_direction==0 ) {	//jumping right

		draw_sprite(Buffer,perso.img_right[NB_IMAGES - 1],perso.x, perso.y);
	}
	if (perso.direction == 2 && last_direction==1) {	//jumping left

		draw_sprite(Buffer, perso.img_left[NB_IMAGES - 1],perso.x, perso.y);
	}
        if (perso.direction == 3 && last_direction==0) {	

		draw_sprite(Buffer, perso.img_right[NB_IMAGES - 4],perso.x,perso.y);
          }
       if (perso.direction == 3  && last_direction==1) {	

		draw_sprite(Buffer, perso.img_left[NB_IMAGES - 4],perso.x, perso.y);
          }

}

/*
 * module collision
 */
 

int get_pixel(BITMAP* Buffer,int x,int y)
{
	int tmp;
	tmp=getpixel(Buffer,x,y);
	return((getr(tmp) + getb(tmp) + getg(tmp)) / 3);
}
